<?php

namespace Leantime\Domain\Plugins\Services;

use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Leantime\Core\Configuration\Environment;
use Leantime\Core\Events\EventDispatcher;
use Leantime\Core\Language;

class Registration
{
    //Plugin Id: folder name of the plugin
    private string $pluginId;

    public function __construct(string $pluginId)
    {
        $this->pluginId = $pluginId;
    }

    public function registerMiddleware(array $middleware)
    {

        EventDispatcher::add_filter_listener('leantime.core.middleware.loadplugins.handle.pluginMiddlware',
            function (array $existing) use ($middleware) {
                return array_merge($existing, $middleware);
            }
        );

    }

    public function registerLanguageFiles(array $languages)
    {

        $pluginId = $this->pluginId;

        EventDispatcher::add_event_listener('leantime.core.middleware.loadplugins.handle.pluginsEvents', function () use ($languages) {

            $language = app()->make(Language::class);
            $config = app()->make(Environment::class);
            $currentUserLanguage = session('usersettings.language');

            //At this point in the stack localization has already determined user language and set up the core language
            //array in the language of the users choice. First we register english if it is in the array and then we
            //override with the user language
            if (in_array('en-US', $languages)) {
                $pluginLangArray = $this->loadPluginLanguage('en-US');
                $language->mergeLanguageArray($pluginLangArray);
            }

            //Now check the user language and override if needed
            if (in_array($currentUserLanguage, $languages)) {
                $pluginLangArray = $this->loadPluginLanguage($currentUserLanguage);
                $language->mergeLanguageArray($pluginLangArray);
            }

        }, 5);

    }

    private function loadPluginLanguage($language): array|false
    {

        if (Cache::store('installation')->has($this->pluginId.'.language.'.$language)) {
            return Cache::store('installation')->get($this->pluginId.'.language.'.$language);
        }

        $pluginPath = APP_ROOT.'/app/Plugins/';

        $pharPath = "phar://{$pluginPath}{$this->pluginId}/{$this->pluginId}.phar";
        $regularPath = "{$pluginPath}{$this->pluginId}";

        $languagePath = "/Language/{$language}.ini";

        //Check phar first
        if (file_exists($pharPath.$languagePath)) {
            $completeLanguagePath = $pharPath.$languagePath;
        } elseif (file_exists($regularPath.$languagePath)) {
            $completeLanguagePath = $regularPath.$languagePath;
        } else {
            //Language file doesn't exist
            Cache::store('installation')->set($this->pluginId.'.language.'.$language, false, Carbon::now()->addDays(7));

            return false;
        }

        $languageArray = parse_ini_file($completeLanguagePath, true);

        //We're caching the results no matter what, language file is not going to magically appear.
        //So even a false is valid as parse_ini_is too expensive to run every time
        Cache::store('installation')->set($this->pluginId.'.language.'.$language, $languageArray, Carbon::now()->addDays(7));

        return $languageArray;

    }

    public function addMenuItem(array $item, string $section, array $location)
    {

        $pluginId = $this->pluginId;

        EventDispatcher::add_filter_listener('leantime.domain.menu.repositories.menu.getMenuStructure.menuStructures.'.$section,
            function ($menu) use ($item, $location, $pluginId) {

                //Prepare
                $item['title'] = "<span class='".$item['icon']."'></span> ".__($item['title']);
                $item['tooltip'] = __($item['tooltip']);
                $item['type'] = 'item';
                $item['module'] = $pluginId;

                $primaryLocationKey = $location[0] ?? $menu[count($menu)];

                if (count($location) <= 1) {
                    $menu[$primaryLocationKey] = $item;
                }

                if (count($location) == 2) {
                    $submenuLocationKey = $location[1] ?? $menu[$primaryLocationKey]['submenu'][count(
                        $menu[$primaryLocationKey]['submenu']
                    )];

                    $menu[$primaryLocationKey]['submenu'][$submenuLocationKey] = $item;

                }

                return $menu;
            },
            50
        );

        EventDispatcher::add_filter_listener('leantime.domain.menu.repositories.menu.getSectionMenuType.menuSections',
            function ($routes) use ($section, $item) {

                $route = str_replace('/', '.', $item['href']);

                $array = explode('.', $route);
                if ($route[0] == '.') {
                    array_shift($array);
                }
                $route = implode('.', $array);

                return array_merge($routes, [$route => $section]);
            },
        );

    }

    public function addHeaderJs(array $middleware) {}

    public function addFooterJs(array $middleware) {}

    public function addCss(array $middleware) {}

    protected function getPluginPath() {}
}
